package com.lty.controller;

import com.lty.common.BaseResponse;
import com.lty.common.ErrorCode;
import com.lty.common.ResultUtils;
import com.lty.exception.BusinessException;
import com.lty.model.dto.code.ApiInfoDTO;
import com.lty.model.dto.code.GenerateRequest;
import com.lty.model.dto.code.SqlDocDTO;
import com.lty.model.dto.code.SqlRequest;
import com.lty.model.dto.code.StringRequest;
import com.lty.model.vo.ApiInfoVO;
import com.lty.service.impl.CodeService;
import com.lty.util.ApiInfoUtil;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;

/**
 * @author lty
 */
@Slf4j
@RequestMapping("/code")
@RestController
public class CodeController {

    @Resource
    private CodeService codeService;

    @ApiOperation(value = "获取生成代码")
    @PostMapping("/generate")
    public BaseResponse<Map<String, String>> generateCode(@RequestBody GenerateRequest request) throws IOException {
        if (request == null) {
            return ResultUtils.error(ErrorCode.PARAMS_ERROR);
        }
        if (request.getTemplates() == null || request.getTemplates().size() == 0) {
            return ResultUtils.error(ErrorCode.PARAMS_ERROR, "请选择模板");
        }
        if (request.getBinding() == null || request.getBinding().size() == 0) {
            return ResultUtils.error(ErrorCode.PARAMS_ERROR, "请填写代码配置");
        }
        return ResultUtils.success(codeService.generateCode(request));
    }

    @ApiOperation(value = "通过SQL得到配置")
    @PostMapping("/configBySql")
    public BaseResponse<Map<String, Object>> configBySql(@RequestBody SqlRequest request) throws Exception {
        if (request == null && StringUtils.isBlank(request.getSql())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        return ResultUtils.success(codeService.configBySql(request.getSql()));
    }

    @ApiOperation(value = "通过本地实体路径得到配置")
    @PostMapping("/configByEntity")
    public BaseResponse<Map<String, Object>> configByEntity(@RequestBody StringRequest request) {
        return ResultUtils.success(codeService.configByEntity(request.getStr()));
    }

    @ApiOperation(value = "获取接口信息")
    @PostMapping("/apiInfo")
    public BaseResponse<List<ApiInfoVO>> getApiInfo(@RequestBody ApiInfoDTO dto) throws Exception {
        if (dto.getApiUrl() == null || dto.getBaseUrl() == null) {
            return ResultUtils.error(ErrorCode.PARAMS_ERROR, "参数错误");
        }
        return ResultUtils.success(ApiInfoUtil.getApiInfoList(dto));
    }

    @ApiOperation(value = "生成数据库文档")
    @PostMapping("/generateSQLDocument")
    public void downloadDocument(HttpServletResponse response, @RequestBody SqlDocDTO dto) throws Exception {
        ByteArrayOutputStream outputStream = codeService.generateAsMemoryStream(dto);
        String timestamp = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        String fileName = dto.getDbName() + "_" + timestamp + dto.getFileType().getFileSuffix();
        fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString()).replaceAll("\\+", "%20");
        response.setHeader("Content-Disposition", "attachment; filename=" + fileName);
        try (InputStream is = new ByteArrayInputStream(outputStream.toByteArray())) {
            IOUtils.copy(is, response.getOutputStream());
        }
    }
}
